﻿#region License
/* Copyright (C) 2009 Tim Coulter
 * 
 * This file is part of ExtremeML.
 * 
 * ExtremeML is free software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public
 * License, as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
*/
#endregion

using System;
using DocumentFormat.OpenXml;

namespace ExtremeML.Core
{
	/// <summary>
	/// Exposes extension methods for converting framework value
	/// types to and from SDK classes that represent simple Xml types.
	/// </summary>
	public static class SimpleTypeExtensions
	{
		/// <summary>
		/// Converts a <see cref="BooleanValue"/> to nullable <see cref="bool"/>.
		/// </summary>
		/// <param name="value">A <see cref="BooleanValue"/> to convert.</param>
		/// <returns>A nullable <see cref="bool"/>.</returns>
		public static bool? ToNullable(
			this BooleanValue value)
		{
			return value.HasValue ? BooleanValue.ToBoolean(value.Value) : default(bool?);
		}

		/// <summary>
		/// Converts a nullable <see cref="bool"/> to a <see cref="BooleanValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="bool"/> to convert.</param>
		/// <returns>A <see cref="BooleanValue"/>.</returns>
		public static BooleanValue ToBooleanValue(
			this bool? value)
		{
			return value.HasValue ? new BooleanValue(value.Value) : new BooleanValue();
		}

		/// <summary>
		/// Converts a <see cref="ByteValue"/> to nullable <see cref="byte"/>.
		/// </summary>
		/// <param name="value">A <see cref="ByteValue"/> to convert.</param>
		/// <returns>A nullable <see cref="byte"/>.</returns>
		public static byte? ToNullable(
			this ByteValue value)
		{
			return value.HasValue ? ByteValue.ToByte(value.Value) : default(byte?);
		}

		/// <summary>
		/// Converts a nullable <see cref="byte"/> to a <see cref="ByteValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="byte"/> to convert.</param>
		/// <returns>A <see cref="ByteValue"/>.</returns>
		public static ByteValue ToByteValue(
			this byte? value)
		{
			return value.HasValue ? new ByteValue(value.Value) : new ByteValue();
		}

		/// <summary>
		/// Converts a <see cref="DateTimeValue"/> to nullable <see cref="DateTime"/>.
		/// </summary>
		/// <param name="value">A <see cref="DateTimeValue"/> to convert.</param>
		/// <returns>A nullable <see cref="DateTime"/>.</returns>
		public static DateTime? ToNullable(
			this DateTimeValue value)
		{
			return value.HasValue ? DateTimeValue.ToDateTime(value.Value) : default(DateTime?);
		}

		/// <summary>
		/// Converts a nullable <see cref="DateTime"/> to a <see cref="DateTimeValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="DateTime"/> to convert.</param>
		/// <returns>A <see cref="DateTimeValue"/>.</returns>
		public static DateTimeValue ToDateTimeValue(
			this DateTime? value)
		{
			return value.HasValue ? new DateTimeValue(value.Value) : new DateTimeValue();
		}

		/// <summary>
		/// Converts a <see cref="DecimalValue"/> to nullable <see cref="Decimal"/>.
		/// </summary>
		/// <param name="value">A <see cref="DecimalValue"/> to convert.</param>
		/// <returns>A nullable <see cref="Decimal"/>.</returns>
		public static decimal? ToNullable(
			this DecimalValue value)
		{
			return value.HasValue ? DecimalValue.ToDecimal(value.Value) : default(decimal?);
		}

		/// <summary>
		/// Converts a nullable <see cref="Decimal"/> to a <see cref="DecimalValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="Decimal"/> to convert.</param>
		/// <returns>A <see cref="DecimalValue"/>.</returns>
		public static DecimalValue ToDecimalValue(
			this decimal? value)
		{
			return value.HasValue ? new DecimalValue(value.Value) : new DecimalValue();
		}

		/// <summary>
		/// Converts a <see cref="DoubleValue"/> to nullable <see cref="Double"/>.
		/// </summary>
		/// <param name="value">A <see cref="DoubleValue"/> to convert.</param>
		/// <returns>A nullable <see cref="Double"/>.</returns>
		public static double? ToNullable(
			this DoubleValue value)
		{
			return value.HasValue ? DoubleValue.ToDouble(value.Value) : default(double?);
		}

		/// <summary>
		/// Converts a nullable <see cref="Double"/> to a <see cref="DoubleValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="Double"/> to convert.</param>
		/// <returns>A <see cref="DoubleValue"/>.</returns>
		public static DoubleValue ToDoubleValue(
			this double? value)
		{
			return value.HasValue ? new DoubleValue(value.Value) : new DoubleValue();
		}

		/// <summary>
		/// Converts a <see cref="Int16Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="Int16Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static int? ToNullable(
			this Int16Value value)
		{
			return value.HasValue ? Int16Value.ToInt16(value.Value) : default(int?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to an <see cref="Int16Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="Int16Value"/>.</returns>
		public static Int16Value ToInt16Value(
			this int? value)
		{
			return value.HasValue ? new Int16Value((Int16)value) : new Int16Value();
		}

		/// <summary>
		/// Converts a <see cref="Int32Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="Int32Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static int? ToNullable(
			this Int32Value value)
		{
			return value.HasValue ? Int32Value.ToInt32(value.Value) : default(int?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to an <see cref="Int32Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="Int32Value"/>.</returns>
		public static Int32Value ToInt32Value(
			this int? value)
		{
			return value.HasValue ? new Int32Value(value.Value) : new Int32Value();
		}

		/// <summary>
		/// Converts a <see cref="Int64Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="Int64Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static int? ToNullable(
			this Int64Value value)
		{
			return value.HasValue ? (int)Int64Value.ToInt64((Int64)value) : default(int?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to a <see cref="Int64Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="Int64Value"/>.</returns>
		public static Int64Value ToInt64Value(
			this int? value)
		{
			return value.HasValue ? new Int64Value((long)value.Value) : new Int64Value();
		}

		/// <summary>
		/// Converts a <see cref="IntegerValue"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="IntegerValue"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static int? ToNullable(
			this IntegerValue value)
		{
			return value.HasValue ? (int)Int64Value.ToInt64(value.Value) : default(int?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to a <see cref="IntegerValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="IntegerValue"/>.</returns>
		public static IntegerValue ToIntegerValue(
			this int? value)
		{
			return value.HasValue ? new IntegerValue((long)value.Value) : new IntegerValue();
		}

		/// <summary>
		/// Converts a <see cref="OnOffValue"/> to nullable <see cref="bool"/>.
		/// </summary>
		/// <param name="value">A <see cref="OnOffValue"/> to convert.</param>
		/// <returns>A nullable <see cref="bool"/>.</returns>
		public static bool? ToNullable(
			this OnOffValue value)
		{
			return value.HasValue ? OnOffValue.ToBoolean(value.Value) : default(bool?);
		}

		/// <summary>
		/// Converts a nullable <see cref="bool"/> to a <see cref="OnOffValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="bool"/> to convert.</param>
		/// <returns>A <see cref="OnOffValue"/>.</returns>
		public static OnOffValue ToOnOffValue(
			this bool? value)
		{
			return value.HasValue ? new OnOffValue(value.Value) : new OnOffValue();
		}

		/// <summary>
		/// Converts a <see cref="SByteValue"/> to nullable <see cref="sbyte"/>.
		/// </summary>
		/// <param name="value">A <see cref="SByteValue"/> to convert.</param>
		/// <returns>A nullable <see cref="sbyte"/>.</returns>
		public static sbyte? ToNullable(
			this SByteValue value)
		{
			return value.HasValue ? SByteValue.ToSByte(value.Value) : default(sbyte?);
		}

		/// <summary>
		/// Converts a nullable <see cref="sbyte"/> to a <see cref="SByteValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="sbyte"/> to convert.</param>
		/// <returns>A <see cref="SByteValue"/>.</returns>
		public static SByteValue ToSByteValue(
			this sbyte? value)
		{
			return value.HasValue ? new SByteValue(value.Value) : new SByteValue();
		}

		/// <summary>
		/// Converts a <see cref="SingleValue"/> to nullable <see cref="Single"/>.
		/// </summary>
		/// <param name="value">A <see cref="SingleValue"/> to convert.</param>
		/// <returns>A nullable <see cref="Single"/>.</returns>
		public static Single? ToNullable(
			this SingleValue value)
		{
			return value.HasValue ? SingleValue.ToSingle(value.Value) : default(Single?);
		}

		/// <summary>
		/// Converts a nullable <see cref="Single"/> to a <see cref="SingleValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="Single"/> to convert.</param>
		/// <returns>A <see cref="SingleValue"/>.</returns>
		public static SingleValue ToSingleValue(
			this Single? value)
		{
			return value.HasValue ? new SingleValue(value.Value) : new SingleValue();
		}

		/// <summary>
		/// Converts a <see cref="TrueFalseValue"/> to nullable <see cref="bool"/>.
		/// </summary>
		/// <param name="value">A <see cref="TrueFalseValue"/> to convert.</param>
		/// <returns>A nullable <see cref="bool"/>.</returns>
		public static bool? ToNullable(
			this TrueFalseValue value)
		{
			return value.HasValue ? TrueFalseValue.ToBoolean(value.Value) : default(bool?);
		}

		/// <summary>
		/// Converts a nullable <see cref="bool"/> to a <see cref="TrueFalseValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="bool"/> to convert.</param>
		/// <returns>A <see cref="TrueFalseValue"/>.</returns>
		public static TrueFalseValue ToTrueFalseValue(
			this bool? value)
		{
			return value.HasValue ? new TrueFalseValue(value.Value) : new TrueFalseValue();
		}

		/// <summary>
		/// Converts a <see cref="TrueFalseBlankValue"/> to nullable <see cref="bool"/>.
		/// </summary>
		/// <param name="value">A <see cref="TrueFalseBlankValue"/> to convert.</param>
		/// <returns>A nullable <see cref="bool"/>.</returns>
		public static bool? ToNullable(
			this TrueFalseBlankValue value)
		{
			return value.HasValue ? TrueFalseBlankValue.ToBoolean(value.Value) : default(bool?);
		}

		/// <summary>
		/// Converts a nullable <see cref="bool"/> to a <see cref="TrueFalseBlankValue"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="bool"/> to convert.</param>
		/// <returns>A <see cref="TrueFalseBlankValue"/>.</returns>
		public static TrueFalseBlankValue ToTrueFalseBlankValue(
			this bool? value)
		{
			return value.HasValue ? new TrueFalseBlankValue(value.Value) : new TrueFalseBlankValue();
		}

		/// <summary>
		/// Converts a <see cref="UInt16Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="UInt16Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static uint? ToNullable(
			this UInt16Value value)
		{
			return value.HasValue ? UInt16Value.ToUInt16(value.Value) : default(uint?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to an <see cref="UInt16Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="UInt16Value"/>.</returns>
		public static UInt16Value ToUInt16Value(
			this uint? value)
		{
			return value.HasValue ? new UInt16Value((UInt16)value) : new UInt16Value();
		}

		/// <summary>
		/// Converts a <see cref="UInt32Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="UInt32Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static uint? ToNullable(
			this UInt32Value value)
		{
			return value.HasValue ? UInt32Value.ToUInt32(value.Value) : default(uint?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to an <see cref="UInt32Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="UInt32Value"/>.</returns>
		public static UInt32Value ToUInt32Value(
			this uint? value)
		{
			return value.HasValue ? new UInt32Value(value.Value) : new UInt32Value();
		}

		/// <summary>
		/// Converts a <see cref="UInt64Value"/> to nullable <see cref="int"/>.
		/// </summary>
		/// <param name="value">A <see cref="UInt64Value"/> to convert.</param>
		/// <returns>A nullable <see cref="int"/>.</returns>
		public static uint? ToNullable(
			this UInt64Value value)
		{
			return value.HasValue ? (uint)UInt64Value.ToUInt64((UInt64)value) : default(uint?);
		}

		/// <summary>
		/// Converts a nullable <see cref="int"/> to a <see cref="UInt64Value"/>.
		/// </summary>
		/// <param name="value">A nullable <see cref="int"/> to convert.</param>
		/// <returns>A <see cref="UInt64Value"/>.</returns>
		public static UInt64Value ToUInt64Value(
			this uint? value)
		{
			return value.HasValue ? new UInt64Value((ulong)value.Value) : new UInt64Value();
		}
	}
}
